﻿using System;
using System.Collections.Generic;
//using System.Text;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
//using CrystalDecisions.ReportAppServer.ClientDoc;
//using CrystalDecisions.ReportAppServer.Controllers;
//using CrystalDecisions.ReportAppServer.DataDefModel; 

namespace ECS.Framework.ReportCR
{
    #region public class
    /// <summary>
    /// Control Report source and display report viewer
    /// </summary>
    public class ReportModule : IDisposable
    {
        #region private properties
        /// <summary>
        /// Report document
        /// </summary>
        private ReportDocument _document = null;
        private TableLogOnInfos _logonInfos = null;
        private TableLogOnInfo _logon = null;
        private ConnectionInfo _connection = null;
        //private Tables _tables = null;
        /// <summary>
        /// Generic / text only printer
        /// </summary>
        private const string PRINTER_TEXT_ONLY = "Generic / Text Only";
        /// <summary>
        /// stop application until next print page in millisecond
        /// </summary>
        private const int PRINT_WAIT_TIME = 10000;
        #endregion

        #region Public properties

        #endregion

        #region constructor
        /// <summary>
        /// constructor
        /// </summary>
        public ReportModule()
        {

        }
        #endregion

        #region Dispose
        /// <summary>
        /// clear resource
        /// </summary>
        public void Dispose()
        {
            try
            {
                if (_document != null)
                {
                    _document.Dispose();
                }
                _document = null;
            }
            catch (Exception)
            {

                throw;
            }
        }
        #endregion

        #region private methods

        #endregion

        #region public method
        /// <summary>
        /// initialize without server connection login info
        /// </summary>
        /// <param name="reportFilePath"></param>
        public void InitialReport(string reportFilePath)
        {
            if (_document != null)
            {
                _document.Close();
                _document.Dispose();
            }
            _document = new ReportDocument();
            _document.Load(reportFilePath);
        }

        public void SetReportFile(string reportFilePath)
        {
            if (_document == null)
            {
                _document = new ReportDocument();
            }
            _document.Load(reportFilePath);
        }
        /// <summary>
        /// Initialize report related components
        /// </summary>
        public void InitialReport(string serverName, string database, string userName, string password, string reportFilePath)
        {
            _document = new ReportDocument();
            _logonInfos = new TableLogOnInfos();
            _logon = new TableLogOnInfo();
            _connection = new CrystalDecisions.Shared.ConnectionInfo();
            Tables tables = null;
            _document.Load(reportFilePath);

            _connection.ServerName = serverName;
            _connection.DatabaseName = database;
            _connection.UserID = userName;
            _connection.Password = password;

            tables = _document.Database.Tables;
            foreach (CrystalDecisions.CrystalReports.Engine.Table tableItem in tables)
            {
                _logon = tableItem.LogOnInfo;
                _logon.ConnectionInfo = _connection;
                tableItem.ApplyLogOnInfo(_logon);
            }

        }
        /// <summary>
        /// load report document by data reader
        /// </summary>
        /// <param name="reader"></param>
        public void LoadReportData(System.Data.IDataReader reader)
        {
            if (_document != null)
            {
                _document.SetDataSource(reader);
            }
        }
        /// <summary>
        /// load report document by enumerable data type
        /// </summary>
        /// <param name="data"></param>
        public void LoadReportData(System.Collections.IEnumerable data)
        {
            if (_document != null)
            {
                _document.SetDataSource(data);
            }
        }
        /// <summary>
        /// load report document by dataset
        /// </summary>
        /// <param name="data"></param>
        public void LoadReportData(System.Data.DataSet data)
        {
            if (_document != null)
            {
                _document.SetDataSource(data);
            }
        }
        /// <summary>
        /// get report parameter
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="paramType"></param>
        /// <returns></returns>
        public CrystalDecisions.Shared.ParameterField GetReportParameter(string name, object value, CrystalDecisions.Shared.ParameterValueKind paramType)
        {
            CrystalDecisions.Shared.ParameterField m_param = new CrystalDecisions.Shared.ParameterField();
            CrystalDecisions.Shared.ParameterDiscreteValue m_paramValue = new CrystalDecisions.Shared.ParameterDiscreteValue();
            m_param.ReportParameterType = CrystalDecisions.Shared.ParameterType.ReportParameter;
            m_param.ParameterValueType = paramType;
            m_param.Name = name;
            m_paramValue.Value = value;
            m_param.CurrentValues.Add(m_paramValue);
            return m_param;
        }

        /// <summary>
        /// set report parameter value
        /// </summary>
        /// <param name="parameterName"></param>
        /// <param name="value"></param>
        public void SetReportParameter(string parameterName, object value)
        {
            _document.ParameterFields[parameterName].CurrentValues.Clear();
            _document.ParameterFields[parameterName].CurrentValues.AddValue(value);
        }

        /// <summary>
        /// Show report on form with viewer
        /// </summary>
        /// <param name="viewer"></param>
        public void ShowReportViewer(ref CrystalDecisions.Windows.Forms.CrystalReportViewer viewer)
        {
            if (_document != null)
            {

                viewer.ReportSource = _document;
                //viewer.RefreshReport();
                viewer.Refresh();
            }
            else
            {
                throw new Exception("Report is not initialized.");
            }
        }
        /// <summary>
        /// set crystal report connection
        /// </summary>
        /// <param name="crDocument"></param>
        public static void SetCrystalReportDataConnection(CrystalDecisions.CrystalReports.Engine.ReportDocument crDocument)
        {
            CrystalDecisions.Shared.TableLogOnInfos crtableLogoninfos = new CrystalDecisions.Shared.TableLogOnInfos();
            CrystalDecisions.Shared.TableLogOnInfo crtableLogoninfo = new CrystalDecisions.Shared.TableLogOnInfo();
            CrystalDecisions.Shared.ConnectionInfo crConnectionInfo = new CrystalDecisions.Shared.ConnectionInfo();
            CrystalDecisions.CrystalReports.Engine.Tables CrTables = crDocument.Database.Tables;
            crConnectionInfo.ServerName = "(local)";
            crConnectionInfo.DatabaseName = "EICS";
            crConnectionInfo.UserID = "";
            crConnectionInfo.Password = "";
            foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in CrTables)
            {
                crtableLogoninfo = CrTable.LogOnInfo;
                crtableLogoninfo.ConnectionInfo = crConnectionInfo;
                CrTable.ApplyLogOnInfo(crtableLogoninfo);
            }
        }
        /// <summary>
        /// print all pages to default printer
        /// </summary>
        public void Print()
        {
            if (_document != null && _document.IsLoaded)
            {
                //ISCDReportClientDocument m_RasDoc;
                //m_RasDoc = _document.ReportClientDocument;
                //PrintOptions opt;
                _document.ReportClientDocument.PrintOutputController.PrintReport();
                //_document.PrintToPrinter(1, true, 0, 0);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pageCount"></param>
        public void PrintWeightSlipTextOnly()
        {
            int pageCount = 0;
            int rowCount = 0;
            object doc = null;
            //string printerName = "Generic / Text Only";
            string tempString = string.Empty;
            System.Threading.AutoResetEvent printEvent = new System.Threading.AutoResetEvent(false);
            try
            {
                //check print document
                doc = _document; // crvViewer.ReportSource;
                if (doc != null && doc.GetType() == typeof(ReportDocument))
                {
                    pageCount = ((ReportDocument)doc).FormatEngine.GetLastPageNumber(new CrystalDecisions.Shared.ReportPageRequestContext());
                    rowCount = _document.Rows.Count;
                    if (pageCount > 0)
                    {
                        //#Test Method 2
                        //print to printer with 16 second long. Wait 20 second during print operation for
                        //the next page to print
                        //System.Drawing.Printing.PrintDocument pDoc = new System.Drawing.Printing.PrintDocument();

                        if (!IsExistPrinter(PRINTER_TEXT_ONLY))
                        {
                            CommonMessageBox.ShowMessageWarning(string.Format("'{0}' printer doesn't exist. Cancel print.", PRINTER_TEXT_ONLY));
                            return;
                        }
                        tempString = GetDefaultPrinter();
                        if (!tempString.Equals(PRINTER_TEXT_ONLY))
                        {
                            tempString = PRINTER_TEXT_ONLY;
                        }

                        CrystalDecisions.ReportAppServer.Controllers.PrintReportOptions rasPROpts = new CrystalDecisions.ReportAppServer.Controllers.PrintReportOptions();
                        //CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper rptClientDoc = new CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper();

                        //pDoc.PrinterSettings.PrinterName = "Generic / Text Only";

                        rasPROpts.PrinterName = tempString;

                        for (int i = 1; i <= pageCount; i++)
                        {
                            // this sets the name of the print job
                            rasPROpts.JobTitle = "Weight Slip page #" + i.ToString();
                            if (i > 1)
                            {
                                if (CommonMessageBox.ShowMessageConfirmYN("Print page : " + i.ToString()) == System.Windows.Forms.DialogResult.No)
                                {
                                    continue;
                                }
                            }
                            rasPROpts.RemoveAllPrinterPageRanges();
                            rasPROpts.AddPrinterPageRange(i, i);
                            ((ReportDocument)doc).ReportClientDocument.PrintOutputController.PrintReport(rasPROpts);
                            if (pageCount > 1 && i < pageCount)
                            {
                                //System.Threading.Thread.Sleep(PRINT_WAIT_TIME);
                                printEvent.WaitOne(PRINT_WAIT_TIME);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                CommonMessageBox.ShowMessageError(ex);
            }
        }
        /// <summary>
        /// Get system default printer
        /// </summary>
        /// <returns></returns>
        public string GetDefaultPrinter()
        {
            string defaultPrinter = string.Empty;
            System.Drawing.Printing.PrinterSettings settings = new System.Drawing.Printing.PrinterSettings();
            foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
            {
                settings.PrinterName = printer;
                if (settings.IsDefaultPrinter)
                {
                    defaultPrinter = printer;
                }
            }
            return defaultPrinter;
        }
        /// <summary>
        /// check printer name exist on system or not
        /// </summary>
        /// <param name="printerName"></param>
        /// <returns></returns>
        public bool IsExistPrinter(string printerName)
        {
            System.Drawing.Printing.PrinterSettings settings = new System.Drawing.Printing.PrinterSettings();
            foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
            {
                settings.PrinterName = printer;
                if (printerName.Equals(printer))
                {
                    return true;
                }
            }
            return false;
        }
        #endregion
    }
    #endregion
}

